/**
 * 编辑器:用于在地球或者建筑节点上编辑子点位.
 * 
 * 数据结构:
 * + 点位表结构(position) {
 *   _id,name,parent,ancestor:[],nodeType:'structure/position',
 *   locationType:'gnss/xy',location:[],areaType:'circle/rectangle/polygon',area:[]
 *   tenant,customer,owner(创建者),createdAt,updatedAt.
 *  }
 * + 点位列表
 * + 当前操作所在节点(即当前parent节点),可能是地球(null)或建筑(structure)
 * 
 * 界面:
 * + 左边节点树(包含创建点位和建筑按钮,分不同形状(null无区域点/circle/rectangle/polygon))
 * + 右边属性框
 *   - 基本属性:名称,父节点,祖先列表,节点类型
 *   - 位置区域属性: 位置类型:gnss/xyz,位置,区域类型,区域
 *   - 扩展插件(面板):关联设备列表框,关联耗材框,可能耗材与设备关联,插件面板带入了各种函数,插件面板本身会带入当前点位信息.
 * + 底部信息框,用来显示操作提示等.
 * + 图表位,可以按广告位方式管理,一般将横向分成M份,纵向分成N份.位置:(0 ~ M-1)/(0 ~ N-1),传入额外参数为当前节点.
 * 
 * 业务逻辑:
 * + 得到第一级节点列表,即查询parent=null的节点列表
 * + 点中某一级的某个节点(不管是在哪一级),界面中parent都是其父节点.如果点中地球,则父节点还在地球,即null.
 * + 点中某个节点,如果是建筑节点,则需要获取其子节点列表,动态加载.
 * 
 * 组件实现:
 * + 属性: 节点保存函数(创建,更新),查找节点函数.
 * + 状态:
 *   - 父节点parent(当前操作节点),
 *   - 节点map(nodeMap)
 *   - 树状结构treeData:[{key(节点_id),title(节点名称name),isLeaf(是否为叶子节点position类型),children:[]},...]
 */
import * as React from 'react';
import LocationEditor from './map/LocationEditor';
import FlowEditor from './flow/FlowEditor';
import { CSSProperties } from 'react';

import Tree from 'rc-tree';
import "rc-tree/assets/index.css"
import './tools.css';
import { AreaType, FullEditorProps, Identifier, NodeType, PositionType, TreeItemType } from './types';
import { addTreeItem, delTreeItem, updateTreeChildren } from './tree';
import { Icon } from './widgets/icon';
import PanelBaseInfo from './widgets/PanelBaseInfo';
import DropdownCreateButton from './widgets/DropdownCreateButton';
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import './tabs.css';

const settingColors = ['#F4F400', '#58CDFF', '#00E39F', '#585EFF', '#FF00E5', '#FF005C', '#FF8A00'];
const warningList = [' 当前不是structure节点! 不能创建子节点!','当前不是structure节点! 不能创建子节点!','当前不是structure节点! 不能创建子节点!'];

const wrapperStyle: CSSProperties = {
  width: '100%',
  height: '100%',
  overflow: 'hidden',
  position: 'relative',
  zIndex: 0,
};

interface FullEditorState {
  defNodeType: NodeType;
  parent?: Identifier;
  current?: Partial<PositionType>;
  nodeMap: { [key: Identifier]: PositionType };
  treeData: TreeItemType[];
  indicatorColor: string;
}
export default function FullEditor(props: FullEditorProps) {
  const { save, remove, retrieve } = props;
  const [state, setState] = React.useState<FullEditorState>({
    nodeMap: {},
    treeData: [],
    defNodeType: 'structure',
    indicatorColor: 'yellow',
  })
  const [satellite, setSatellite] = React.useState(false); //卫星选中状态
  const [colorShow, setColorShow] = React.useState(false); //颜色列表展开状态
  const [warningShow, setWarningShow] = React.useState(false); //日志列表打开状态

  const handleChangeNodeType = React.useCallback((evt: React.ChangeEvent<HTMLInputElement>) => {
    console.log('handleChangeNodeType', evt);
    const nodeType1 = evt.target.value as NodeType;
    const checked = evt.target.checked;
    if (checked) {
      setState(state => ({...state, defNodeType: nodeType1}));
    }
  },[]);
  const handleSelect = React.useCallback((info: any) => {
    console.log('selected 当前节点', info);
    const key1 = info && info[0];
    setState(state => {
      const current = state.nodeMap[key1];
      const parentId = current?.parent;
      return { ...state, parent: parentId, current }
    })
  }, []);

  const handleCheck = React.useCallback((checkedKeys: any) => {
    console.log('handleCheck', checkedKeys);
    const key1 = checkedKeys && checkedKeys[0];
    setState(state => {
      const node = state.nodeMap[key1];
      return { ...state, current: node }
    })
  }, []);

  const handleLoadChildren = React.useCallback(async (treeNode: any) => {
    const qopts = (treeNode.key === 'earth') ? { where: { parent: null } } : { where: { parent: treeNode.key } };
    const result = await retrieve(qopts);
    console.log('load data...', treeNode, result);
    setState(state => {
      const nodeMap1 = result.items.reduce((prev: any, item: any) => {
        return { ...prev, [item._id]: item };
      }, {});
      const children = result.items.map((item_1: any) => {
        return { key: item_1._id, title: item_1.name, isLeaf: item_1.nodeType === 'position' };
      });

      const nTreeData = updateTreeChildren(state.treeData, treeNode.key, children) || []
      // treeDataWithEarth[0].children = nTreeData;
      return { ...state, nodeMap: { ...state.nodeMap, ...nodeMap1 }, treeData: nTreeData };
    });
  }, []);

  const handleChangeCurrent = React.useCallback((value: Partial<PositionType>) => {
    console.log('handleChangeCurrent', value);
    setState(state => ({ ...state, current: value }))
  }, []);
  const handleChangeParent = React.useCallback((_id: Identifier) => {
    console.log('handleChangeParent', _id);
    setState(state => {
      return { ...state, parent: _id, current: undefined }
    });
  }, []);
  const handleSavePosition = React.useCallback((value: Partial<PositionType>) => {
    console.log('handleSavePosition', value);
    save(value).then((record: PositionType) => {
      setState(state => {
        const nTreeData = addTreeItem(state.treeData, record.parent, { key: record._id, title: record.name, isLeaf: record.nodeType === 'position' }) || [];
        // treeDataWithEarth[0].children = nTreeData;
        return { ...state, current: record, nodeMap: { ...(state.nodeMap || {}), [record._id]: record }, treeData: nTreeData };
      })
    });
  }, []);
  const handleRemovePosition = React.useCallback(async (_id?: Identifier) => {
    console.log('handleRemovePosition', _id);
    if (_id) {
      await remove(_id);
      setState(state => {
        const nTreeData = delTreeItem(state.treeData, _id) || [];
        return { ...state, current: undefined, treeData: nTreeData };
      })
    } else {
      setState(state => {
        return { ...state, current: undefined };
      })
    }
  }, []);

  const parent = state.parent;
  const parentItem = parent ? state.nodeMap[parent] : undefined;
  const locationType = !parent ? 'gnss' : 'xyz'; // 顶层节点是gnss.
  const currentId = state.current?._id || state.current?.id;

  const handleSelectTool = React.useCallback((value: { nodeType: NodeType; areaType: AreaType }, levelType: 'sibling' | 'child' = 'sibling') => {
    if (!value) {
      console.log('no value! 不能创建节点!');
      return;
    }
    if (levelType === 'sibling') {
      // 创建同级节点
      let currentAncestor = parentItem?.ancestor || [];
      if (parent) currentAncestor = [...currentAncestor, parent];
      setState(state => {
        return {
          ...state, current: {
            name: state.defNodeType === 'structure' ? '新建筑' : '新节点',
            parent,
            ancestor: currentAncestor,
            nodeType: state.defNodeType,
            locationType,
            areaType: value.areaType,
          }
        }
      });
    } else {
      // 创建子级节点, 根据current构建基础内容.
      if (!currentId) {
        console.log('no current.id! 不能创建子节点!');
        return;
      }
      if (state.current?.nodeType !== 'structure') {
        console.log('当前不是structure节点! 不能创建子节点!');
        return;
      }
      let currentAncestor = state.current?.ancestor || [];
      if (currentId) currentAncestor = [...currentAncestor, currentId];

      setState(state => {
        return {
          ...state, current: {
            name: state.defNodeType === 'structure' ? '新建筑' : '新节点',
            parent: currentId,
            ancestor: currentAncestor,
            nodeType: state.defNodeType,
            locationType,
            areaType: value.areaType,
          },
          parent: currentId,
        }
      });
    }
  }, [parent, parentItem?.ancestor, locationType, state.current?.nodeType, currentId]);

  const canCreateChild = currentId && state.current?.nodeType === 'structure';
  const treeDataWithEarth2 = [{
    key: 'earth',
    title: '地球',
    expanded: true,
    isLeaf: false,
    children: state.treeData,
  }];
  console.log('FullEditor', {canCreateChild, currentId, })
  return (
    <div style={{ ...wrapperStyle }}>
      {/* <FlowEditor /> */}
      <div className="search-wrap">
        <div className="search-wrap-title">
          <div className="rc-panel-title">位置搜索</div>
          <div className="satelliteWrap" onClick={() => setSatellite(!satellite)}><Icon name='icon-satellite' color={satellite ? '#3D5AFE' : '#BDBDBD'} /><span style={{ color: satellite ? '#3D5AFE' : '#BDBDBD' }}>卫星</span></div>
        </div>
        <input className="customInput" style={{ width: '100%' }} value={''} type='input' placeholder='输入地址/位置' />
      </div>
      {!parent ? <LocationEditor dbNodeMap={state.nodeMap} dbNodeTree={state.treeData} parent={parentItem} value={state.current} onChange={handleChangeCurrent} satellite={satellite} /> : <FlowEditor dbNodeMap={state.nodeMap} dbNodeTree={state.treeData} parent={parentItem} value={state.current} onChange={handleChangeCurrent} />}
      <aside className='rc-aside-panel'>
        <div style={{ padding: '16px 20px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <div className='rc-panel-title'>新增节点</div>
            <div>
              <label style={{display: 'flex', alignItems: 'center'}}>
                <input type="radio" value="structure" checked={state.defNodeType === 'structure'} onChange={handleChangeNodeType} />
                <span>建筑</span>
                <input type="radio" value="position" checked={state.defNodeType === 'position'} onChange={handleChangeNodeType} />
                <span>点位</span>
              </label>
            </div>
          </div>
          <div className="createNodeWrap">
            <DropdownCreateButton type='sibling' onCreate={handleSelectTool} />
            <div style={{ width: 10, flex: 1 }}></div>
            <DropdownCreateButton type='child' disabled={!canCreateChild} onCreate={handleSelectTool} />
          </div>
        </div>
        <div style={{ borderRadius: '10px', maxHeight: '500px', overflowY: 'hidden' }}>
          <div style={{ padding: '10px 20px 50px 20px', overflowY: 'scroll' }}>
            <div className='search-wrap-title'>
              <div className='rc-panel-title'>点位层级</div>
              <div className="satelliteWrap">
                <Icon name='icon-list' />
                <span style={{ color: '#2979FF' }}>列表模式</span>
              </div>
            </div>
            <Tree
              onSelect={handleSelect}
              checkable={false}
              onCheck={handleCheck}
              checkedKeys={state.current?._id}
              loadData={handleLoadChildren}
              treeData={treeDataWithEarth2}
            />
          </div>
        </div>
      </aside>
      <div className='rc-property-panel'>
        <Tabs style={{ paddingBottom:'20px' }}>
          <TabList>
            <Tab>基本信息</Tab>
            <Tab>建筑详情</Tab>
            <Tab>关联设备</Tab>
          </TabList>
          <TabPanel className="tabPage">
            <PanelBaseInfo dbNodeMap={state.nodeMap} value={state.current} onChange={handleChangeCurrent} onChangeParent={handleChangeParent} onSubmit={handleSavePosition} onRemove={handleRemovePosition} />
          </TabPanel>
          <TabPanel className="tabPage">
            无
          </TabPanel>
          <TabPanel className="tabPage">
            <div>
              <div style={{ display: 'flex', alignItems: 'center' }}>
                <h3>关联设备</h3>
                <div style={{ fontSize: '11px' }}>
                  <span style={{ marginLeft: '15px' }}>ID:</span>
                  <span>{state.current?._id}</span>
                </div>
              </div>
              <div className="infoDiv">
                <Icon name="icon-info" size={35} />
                <div style={{ color: '#0288D1', marginLeft: '10px' }}>能点信息会影响固件开发、设备事件、控制界面，如果修改功能点信息，请确定相关信息是否受影响。</div>
              </div>
            </div>
          </TabPanel>
        </Tabs>
      </div>
      <div className='setting-wrap'>
        <Icon name="icon-setting" color={'#000'} onClick={() => setColorShow(!colorShow)}/>
        {colorShow ? <div className='color-list'>
          <span style={{ marginLeft: '10px', fontSize: '13px' }}>顶点颜色</span>
          {settingColors.map((item: any) => {
            return <div className='setting-item' style={{ background: item }} onClick={()=>setState(state =>({...state, indicatorColor: item}))}></div>
          })}
        </div> : null}
      </div>
      <div className='warning-wrap'>
        <Icon name="icon-warning" color={'#000'} onClick={() => setWarningShow(!warningShow)} />
        {warningShow ? <div className='warning-list'>
          {warningList.map((item: any) => {
            return <div className='warning-item'>
              <span style={{color:'#9E9E9E',marginRight:'10px'}}>2024-01-10 10:23:34</span>
              <span>{item}</span>
            </div>
          })}
        </div> : null}
      </div>
    </div>
  )
}
